package com.itheima.health.controller;


import com.itheima.health.common.MessageConst;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.Member;
import com.itheima.health.pojo.Setmeal;
import com.itheima.health.service.MemberService;
import com.itheima.health.service.OrderService;
import com.itheima.health.service.ReportService;
import com.itheima.health.service.SetMealService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


@Slf4j
@RestController
@RequestMapping("report")
public class ReportController {

    @DubboReference
    private MemberService memberService;
    @DubboReference
    private SetMealService setMealService;
    @DubboReference
    private OrderService orderService;
    @DubboReference
    private ReportService reportService;

    @PreAuthorize("hasAuthority('REPORT_VIEW')")
    @GetMapping("getMemberReport")
    public Result getMemberReport(String starttime,String endtime) {
        /*
         * @Date: 4:19 下午 2021/1/15
         * @name: getMemberReport
         * @param: []
         * @return: com.itheima.health.entity.Result
         * @Description: 获取会员一年的增长数据
         */
        log.info(starttime);
        log.info(endtime);
        int a = 1;
        String start= starttime;
        String end= endtime;
        List<String> months = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM");
        //*********转类型实验******************************
        Calendar startcalendar = Calendar.getInstance();
        Calendar endcalendar = Calendar.getInstance();
        try {
            Date date =sdf.parse(starttime);
            log.info("[会员统计-格式化日志] - date: {}",date);
            Date date2 =sdf.parse(endtime);
            startcalendar.setTime(date);
            endcalendar.setTime(date2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        log.info("[会员统计-开始时间] - startcalendar: {}",startcalendar);
        int chazhi = betweenMonthByTwoCalendar(startcalendar,endcalendar);
        log.info("[会员统计-开始时间与结束时间的差值]:{}",chazhi);
        //************************************************
        //获取当前日期
        //Calendar cal = Calendar.getInstance();
        //当前时间-12就是一年之前的时间，并存入日历
        //cal.set(Calendar.MONTH, -12);

        for (int i = 0; i <= chazhi; i++) {
            //将当前时间格式化
            String strDate = sdf.format(startcalendar.getTime());
            //每获取一次时间月份+1
            //cal.add(Calendar.MONTH, 1);
            startcalendar.add(startcalendar.MONTH,1);
            months.add(strDate);
        }
        List<Integer> memberCount = memberService.countByMonth(months);
        Map<String, Object> map = new HashMap<>();
        map.put("months", months);
        map.put("memberCount", memberCount);
        log.info("[会员统计-1～12月份统计-返回会员报告] -map: {}", map);
        if (map == null) {
            return new Result(false, MessageConst.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
        return new Result(true, MessageConst.GET_MEMBER_NUMBER_REPORT_SUCCESS, map);
    }

    //**********************计算日期差**********************************
    public static int betweenMonthByTwoCalendar(Calendar startCalendar,Calendar endCalendar){
        //判断日期大小
        if(startCalendar.after(endCalendar)){
            Calendar temp = startCalendar;
            startCalendar = endCalendar;
            endCalendar = temp;
        }
        int startYear = startCalendar.get(Calendar.YEAR);
        int endYear = endCalendar.get(Calendar.YEAR);
        int startMonth = startCalendar.get(Calendar.MONTH);
        int endMonth = endCalendar.get(Calendar.MONTH);
        int monthNum = (endYear - startYear)*12+(endMonth-startMonth);
        return monthNum;
    }

    @PreAuthorize("hasAuthority('REPORT_VIEW')")
    @GetMapping("getSetmealReport")
    public Result getSetMealReport() {
        /*
         * @Date: 6:03 下午 2021/1/15
         * @name: getSetMealReport
         * @param: []
         * @return: com.itheima.health.entity.Result
         * @Description:
         * 1、查询setmeal表获取所有的套餐id和名字（名字用来返回给前端作展示使用）
         * 2、根据setmealID查询order表查看每个套餐有多少人使用
         */

        Map<String, Object> resultMap = new HashMap<>();

        List<Map<String, Object>> setmealCount = new ArrayList<>();
        List<String> setmealNames = new ArrayList<>();

        //查询所有的套餐，遍历所有的套餐并获取套餐id，根据套餐id去order表中查
        List<Setmeal> setMealList = setMealService.findAll();
        for (Setmeal setmeal : setMealList) {
            Integer countSetMeal = orderService.countBySetMealId(setmeal.getId());
            setmealNames.add(setmeal.getName());
            Map<String, Object> map = new HashMap<>();
            map.put("name", setmeal.getName());
            map.put("value", countSetMeal);
            setmealCount.add(map);
        }
        resultMap.put("setmealNames", setmealNames);
        resultMap.put("setmealCount", setmealCount);
        log.info("[套餐统计-返回套餐报告统计] - resultMap: {}", resultMap);
        if (setmealCount == null) {
            return new Result(false, MessageConst.GET_SETMEAL_COUNT_REPORT_FAIL);
        }
        return new Result(true, MessageConst.GET_SETMEAL_COUNT_REPORT_SUCCESS, resultMap);
    }

    /*
    套餐会员报表统计
     */
    @GetMapping("getBusinessReportData")
    public Result getBusinessReportData() {

        Map<String, Object> map = reportService.getBusinessReportData();
        if (map==null){
            return new Result(false,MessageConst.GET_SETMEAL_COUNT_REPORT_FAIL);
        }

        return new Result(true,MessageConst.GET_SETMEAL_COUNT_REPORT_SUCCESS,map);
    }

    /*
    导出套餐会员报表
     */
    @GetMapping("exportBusinessReport")
    public Result exportBusinessReport(HttpServletResponse response){
        Map<String, Object> map = reportService.getBusinessReportData();
        //获取日期
        String date = (String) map.get("reportDate");
        //新增会员数
        long todayNewMember = (long) map.get("todayNewMember");
        //本周新增会员数
        long thisWeekNewMember = (long) map.get("thisWeekNewMember");
        //本月新增会员数
        long thisMonthNewMember = (long) map.get("thisMonthNewMember");
        //总会员数
        long totalMember = (long) map.get("totalMember");
        //今日预约数
        long todayOrderNumber = (long) map.get("todayOrderNumber");
        //本周预约数
        long thisWeekOrderNumber = (long) map.get("thisWeekOrderNumber");
        //本月预约数
        long thisMonthOrderNumber = (long) map.get("thisMonthOrderNumber");
        //今日到诊数
        long todayVisitsNumber = (long) map.get("todayVisitsNumber");
        //本周到诊数
        long thisWeekVisitsNumber = (long) map.get("thisWeekVisitsNumber");
        //本月到诊数
        long thisMonthVisitsNumber = (long) map.get("thisMonthVisitsNumber");
        //最热商品
        List<Map> hotSetmeal = (List<Map>) map.get("hotSetmeal");

        //可以省略关流操作
        try(InputStream is = this.getClass().getClassLoader().getResourceAsStream("report_template.xlsx");
            ServletOutputStream os = response.getOutputStream();
            XSSFWorkbook workbook = new XSSFWorkbook(is)
        ) {
            XSSFSheet sheet = workbook.getSheetAt(0);
            sheet.getRow(2).getCell(5).setCellValue(date);
            sheet.getRow(4).getCell(5).setCellValue(todayNewMember);
            sheet.getRow(4).getCell(7).setCellValue(totalMember);
            sheet.getRow(5).getCell(5).setCellValue(thisWeekNewMember);
            sheet.getRow(5).getCell(7).setCellValue(thisMonthNewMember);
            sheet.getRow(7).getCell(5).setCellValue(todayOrderNumber);
            sheet.getRow(8).getCell(5).setCellValue(thisWeekOrderNumber);
            sheet.getRow(9).getCell(5).setCellValue(thisMonthOrderNumber);
            sheet.getRow(7).getCell(7).setCellValue(todayVisitsNumber);
            sheet.getRow(8).getCell(7).setCellValue(thisWeekVisitsNumber);
            sheet.getRow(9).getCell(7).setCellValue(thisMonthVisitsNumber);
            int rowNum = 12;
            for (Map setmeal : hotSetmeal) {
                sheet.getRow(rowNum).getCell(4).setCellValue((String) setmeal.get("name"));
                sheet.getRow(rowNum).getCell(5).setCellValue((long) setmeal.get("setmeal_count"));
                sheet.getRow(rowNum).getCell(6).setCellValue(((BigDecimal) setmeal.get("proportion")).doubleValue());
                rowNum++;
            }
            //设置响应头数据
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition", "attachment;fileName=" + date + "_report.xlsx");
            //把文件放入http中返回
            workbook.write(os);
            return null;
        } catch (IOException e) {
            log.error("",e);
            return new Result(false,MessageConst.ACTION_FAIL);
        }
    }



/**
 * @Author: oooo
 * @Date: 18:07 2021/1/20
 * @Parms []
 * @ReturnType: com.itheima.health.entity.Result
 * @Description: 年龄占比饼图
*/


    @RequestMapping("/getMemberAgeReport")
    public Result getMemberAgeReport(){
        List<Map<String, Object>> countByAge = new ArrayList<>();
        // 定义一个集合,集合中存入自定义的年龄段
      //  List<String> memberAges = Arrays.asList();
        List<String> memberAges = new ArrayList<>();
        memberAges.add("0-18");
        memberAges.add("19-30");
        memberAges.add("31-45");
        memberAges.add("45以上");
        //memberAges.add("0往上");

        // 调用service 获取年龄
        List<Integer> memberAgeList = memberService.findMemberAgeCount();
        Map<String,Object> map = new HashMap<>();

        for (Integer age : memberAgeList) {
            if (age <= 18){
                Integer count = 0;
                if (null != map.get("0-18")){
                    count = Integer.parseInt(String.valueOf(map.get("0-18")));
                    map.put("0-18",++count);
                    continue;
                }
                map.put("0-18",++count);
            } else if (19 <= age && age<= 30){
                Integer count = 0;
                if (null != map.get("19-30")){
                    count = Integer.parseInt(String.valueOf(map.get("19-30")));
                    map.put("19-30",++count);
                    continue;
                }
                map.put("19-30",++count);
            }else if (31 <= age && age<= 45){
                Integer count = 0;
                if (null != map.get("31-45")){
                    count = Integer.parseInt(String.valueOf(map.get("31-45")));
                    map.put("31-45",++count);
                    continue;
                }
                map.put("31-45",++count);
            }else if (45 < age ){
                Integer count = 0;
                if (null != map.get("45以上")){
                    count = Integer.parseInt(String.valueOf(map.get("45以上")));
                    map.put("45以上",++count);
                    continue;
                }
                map.put("45以上",++count);
            }
        }

        // 遍历年龄段

        for (String memberAge : memberAges) {
            Map<String,Object> map1 = new HashMap<>();
            map1.put("name",memberAge);
            map1.put("value",map.get(memberAge));
            countByAge.add(map1);
        }
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("memberAges",memberAges);
        resultMap.put("countByAge",countByAge);


        return new Result(true,MessageConst.QUERY_SETMEAL_SUCCESS,resultMap);


    }

}
